package geektime.io.nio2.demo;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class AfcDemo {

    public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
        if (args.length == 0) {
            System.err.println("There is no file");
            return;
        }
        Path path = Paths.get(args[0]);
        readAsFuture(path);
        readByHandler(path);
    }

    private static void readAsFuture(Path path) throws IOException, ExecutionException, InterruptedException {
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path);
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        Future<Integer> readFuture = fileChannel.read(byteBuffer, 0);
        while (!readFuture.isDone()) {
            try {
                System.out.println("sleep till get the future result");
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        Integer readResult = readFuture.get();
        System.out.println("The read result=" + readResult);
        fileChannel.close();
    }

    private static void readByHandler(Path path) throws IOException {
        AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path);
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Thread mainThread = Thread.currentThread();
        fileChannel.read(buffer, 0, null, new CompletionHandler<Integer, Void>() {
            @Override
            public void completed(Integer result, Void attachment) {
                System.out.println("Read completed..., result=" + result);
                mainThread.interrupt();
            }

            @Override
            public void failed(Throwable exc, Void attachment) {
                System.out.println("Read encountered error");
                mainThread.interrupt();
            }
        });
        System.out.println("Wait for completion");
        try {
            mainThread.join();
        } catch (InterruptedException e) {
            System.out.println("Read terminated");
        }
    }
}
